package com.mapforge.map.tools.undo.tilemapedit;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.mapforge.Constants;
import com.mapforge.map.Tile;
import com.mapforge.map.TileLayer;
import com.mapforge.map.TileMap;

public class TileMapResizeEdit extends AbstractTilemapEdit {

	private int newWidth;
	private int newHeight;
	private int oldWidth;
	private int oldHeight;

	/**
	 * Tiles saved from change in width.
	 */
	private List<Tile[][]> widthSave;
	/**
	 * Tiles save from change in height.
	 */
	private List<Tile[][]> heightSave;

	public TileMapResizeEdit(TileMap tileMap, int newWidth, int newHeight) {
		super(tileMap, Constants.LAYER_EDITED, "Map Resize");

		this.newWidth = newWidth;
		this.newHeight = newHeight;
		this.oldWidth = tileMap.getTotalHorizontalTiles();
		this.oldHeight = tileMap.getTotalVerticalTiles();

		// need to save tiles if they'd be lost in resize
		if (this.newWidth < this.oldWidth) {
			this.widthSave = new ArrayList<Tile[][]>(tileMap
					.getNumberTileLayers());

			Iterator<TileLayer> it = tileMap.getTileLayerIterator();
			TileLayer layer;
			Tile[][] data;
			Tile[][] tilesToSave;
			int xlim = this.newWidth - this.oldWidth;
			while (it.hasNext()) {
				layer = it.next();
				data = layer.getData();
				tilesToSave = new Tile[newHeight][xlim];
				// save tiles lost in resize
				for (int y = 0; y < newHeight; y++) {
					for (int x = oldWidth; x < newWidth; x++) {
						tilesToSave[y][x - oldWidth] = data[y][x];
					}
				}
				widthSave.add(tilesToSave);
			}
		}
		// save tiles to corner if no overlap with width save.
		if (this.newHeight < this.oldHeight) {
			this.heightSave = new ArrayList<Tile[][]>(tileMap
					.getNumberTileLayers());
			Iterator<TileLayer> it = tileMap.getTileLayerIterator();
			TileLayer layer;
			Tile[][] data;
			Tile[][] tilesToSave;
			int yLim = this.oldHeight - this.newHeight;
			int xLim = newWidth;
			if (newWidth > oldWidth) {
				xLim = oldWidth;
			}
			while (it.hasNext()) {
				layer = it.next();
				data = layer.getData();
				tilesToSave = new Tile[yLim][xLim];
				for (int y = oldHeight; y < newHeight; y++) {
					for (int x = 0; x < xLim; x++) {
						tilesToSave[y - oldHeight][x] = data[x][y];
					}
				}
				heightSave.add(tilesToSave);
			}
		}
	}

	@Override
	public void die() {
		this.setTilemap(null);
		this.setIcon(null);
		this.widthSave = null;
		this.heightSave = null;
		this.newHeight = 0;
		this.oldHeight = 0;
		this.newWidth = 0;
		this.oldWidth = 0;
	}

	@Override
	public void redo() {
		// TODO Auto-generated method stub

	}

	@Override
	public void undo() {
		// TODO Auto-generated method stub

	}

}
